package com.neutech.maplestory.entity;

import com.neutech.maplestory.client.MapleStoryClient;
import com.neutech.maplestory.constant.Constant;
import com.neutech.maplestory.util.ImageUtil;
import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;
import org.omg.CORBA.PUBLIC_MEMBER;


import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.List;
import java.util.Random;

public class Hero extends AbstractMapleObject{
    public static Image[] imgs = new Image[100];
    static {
        for (int i = 0; i < 4; i++) {
            imgs[i] = ImageUtil.getImage("hero_right_stand" + i );
        }
        for (int i = 4; i < 8; i++) {
            imgs[i] = ImageUtil.getImage("hero_left_stand" + (i -4) );
        }
        for (int i = 8; i < 13; i++) {
            imgs[i] = ImageUtil.getImage("hero_right_walk" + (i -8) );
        }
        for (int i = 13; i < 18; i++) {
            imgs[i] = ImageUtil.getImage("hero_left_walk" + (i -13) );
        }
        imgs[18] = ImageUtil.getImage("hero_right_prone");
        imgs[19] = ImageUtil.getImage("hero_left_prone");
        imgs[20] = ImageUtil.getImage("hero_right_jump");
        imgs[21] = ImageUtil.getImage("hero_left_jump");
        for (int i = 22; i < 26; i++) {
            imgs[i] = ImageUtil.getImage("hero_right_shoot" + (i - 22) );
        }
        for (int i = 26; i < 30; i++) {
            imgs[i] = ImageUtil.getImage("hero_left_shoot" + (i - 26) );
        }
        imgs[30] = ImageUtil.getImage("bg");
        imgs[31] = ImageUtil.getImage("rope");


    }

    public MapleStoryClient msc;
    public int exp;
    public int grade =1;
    public Hero(){}

    public int MP;
    /**
     * 人物魔法值上限
     */
    public int MAX_MP = 1000;
    public int HP;
    /**
     * 人物血量上限
     */
    public int MAX_HP = 1000;
    /**
     * 基础攻击力
     */
    public int ATT;
    /**
     * 伤害值
     */
    public int hitValue;

    public Random r = new Random();

    public Hero(MapleStoryClient msc,int x,int y){
        this.msc = msc;
        this.x = x;
        this.y = y;
        this.MP = MAX_MP;
        this.HP = MAX_HP;
        this.ATT = 2000;
        this.speed = Constant.HERO_SPEED;
        this.width = imgs[0].getWidth(null);
        this.height = imgs[0].getHeight(null);
        this.dir = Direction.RIGHT;
        this.action = Action.STAND;
        this.exp = 0;
    }

    /**
     * 一直加的计数器
     */
    private int count = 0;
    /**
     * 计算当前画第几张图
     */
    private int step = 0;
    /**
     *  左右的开关
     */
    public boolean left,right,down,jump,shoot,pickup,rope;
    @Override
    public void  draw(Graphics g) {
        //TODO
        g.drawImage(imgs[30],0,0,null);
        switch (action) {
            case ROPE:
                g.drawImage(imgs[31], x, y, null);
                break;
            default:
                break;
        }
        switch (dir){
            case UP:
                switch (action) {
                    case WALK:
                        // right walk
                        if(count++ % 3 == 0){
                            g.drawImage(imgs[(step++ % 5) + 8],x,y,null);
                        }else {
                            g.drawImage(imgs[step % 5 + 8],x,y,null);
                        }
                        break;
                    case PRONE:
                        g.drawImage(imgs[18],x+10,y + 32,null);
                        break;
                    case JUMP:
                        g.drawImage(imgs[20],x,y,null);
                        break;
                    case SHOOT:
                        // right SHOOT
                        if(count++ % 3 == 0){
                            g.drawImage(imgs[step++ % 4 + 22],x,y,null);
                        }else {
                            g.drawImage(imgs[step% 4 + 22 ],x,y,null);
                        }
                        break;
                    case STAND:
                        if (count++ % 3 == 0) {
                            g.drawImage(imgs[(step % 4) + 4], x, y, null);
                            step++;
                        } else {
                            g.drawImage(imgs[(step % 4) + 4], x, y, null);
                        }
                        break;
                    /*case ROPE:
                        g.drawImage(imgs[31], x, y, null);
                        break;*/
                    default:
                        break;
                }
                break;
//                    case PRONE:
//                        g.drawImage(imgs[19],x-10,y+imgs[19].getWidth(null)/2,null);
//                        break;
//                    case JUMP:
//                        g.drawImage(imgs[21],x,y,null);
//                        break;
//                    case SHOOT:
//                        if (count++ % 3 == 0) {
//                            g.drawImage(imgs[(index % 4) + 26],x,y,null);
//                            index++;
//                        } else {
//                            g.drawImage(imgs[(index % 4) + 26],x,y,null);
//                        }
//                        break;
            /*case UP:
               *//* switch (action){
                case ROPE:*//*
                    g.drawImage(imgs[31],x,y,null);
                    break;
               *//* default:
                    break;
                }*/
            case RIGHT:
                switch (action){
                    case STAND:
                        // right stand
                        if(count++ % 3 == 0){
                            g.drawImage(imgs[step++ % 4],x,y,null);
                        }else {
                            g.drawImage(imgs[step% 4],x,y,null);
                        }
                        break;
                    case WALK:
                        // right walk
                        if(count++ % 3 == 0){
                            g.drawImage(imgs[(step++ % 5) + 8],x,y,null);
                        }else {
                            g.drawImage(imgs[step % 5 + 8],x,y,null);
                        }
                        break;
                    case PRONE:
                        g.drawImage(imgs[18],x+10,y + 32,null);
                        break;
                    case JUMP:
                        g.drawImage(imgs[20],x,y,null);
                        break;
                    case SHOOT:
                        // right SHOOT
                        if(count++ % 3 == 0){
                            g.drawImage(imgs[step++ % 4 + 22],x,y,null);
                        }else {
                            g.drawImage(imgs[step% 4 + 22 ],x,y,null);
                        }
                        break;
                   /* case ROPE:
                        g.drawImage(imgs[31],x,y,null);
                        break;*/
                    default:
                        break;
                }
                break;

            case LEFT:
                switch (action){
                    case STAND:
                        // left stand
                        if(count++ % 3 == 0){
                            g.drawImage(imgs[(step++ % 4) + 4],x,y,null);
                        }else {
                            g.drawImage(imgs[step % 4 + 4],x,y,null);
                        }
                        break;
                    case WALK:
                        // left walk
                        if(count++ % 3 == 0){
                            g.drawImage(imgs[(step++ % 5) + 13],x,y,null);
                        }else {
                            g.drawImage(imgs[step % 5 + 13],x,y,null);
                        }
                        break;
                    case PRONE:
                        g.drawImage(imgs[19],x - 10,y + 32,null);
                        break;
                    case JUMP:
                        g.drawImage(imgs[21],x,y,null);
                        break;
                    case SHOOT:
                        // LEFT SHOOT
                        if(count++ % 3 == 0){
                            g.drawImage(imgs[step++ % 4 + 26],x,y,null);
                        }else {
                            g.drawImage(imgs[step% 4 + 26],x,y,null);
                        }
                        break;
                    /*case ROPE:
                        g.drawImage(imgs[31],x,y,null);
                        break;*/
                    default:
                        break;
                }
                break;
            default:
                break;
        }

            bloodBar.draw(g);


            mp.draw(g);
        Font f = g.getFont();
        g.setFont(new Font("幼圆",Font.BOLD,30));
        g.drawString("LV" + msc.hero.grade,this.x ,this.y-30);
        g.setFont(f);
        move();
    }

    @Override
    public void move() {
        if (left){
            x -= speed;
            this.action = Action.WALK;
        }
        if (right){
            x +=speed;
            this.action = Action.WALK;
        }
        if (rope && !left && !right){
            y -= speed;
            this.dir = Direction.UP;
        }else {
            if (jump) {
                jump(msc.grounds);
            }else {
                // 自由落体
                jumpDown(msc.grounds);
            }
        }

       /* if (rope){
            y -= speed;
            this.action = Action.ROPE;
            dir = Direction.UP;
        }else{
            if (jump){
                jump(msc.grounds);
            }else{
                jumpDown(msc.grounds);
            }
        }*/

        if (shoot){
            shoot();
        }
        if (pickup){
            pickup(msc.items);
        }
        outOfBound();
        confirmDirection();
    }

    /**
     *射击持续时长
     */
    private int shootCount;

    /**
     * 射击方法
     */
    private void shoot() {
        shootCount++;

        if (shootCount % 10 ==0){
            shoot = false;
            this.MP -=5;
            Arrow arrow;
            if (dir ==Direction.RIGHT){
                arrow = new Arrow(msc,x+this.width,y+this.height/2 +8 ,dir);
            }else {
                arrow = new Arrow(msc,x,y+this.height/2+8,dir);
            }

            msc.arrows.add(arrow);
        }
    }

    private double v0 =Constant.INIT_JUMP_SPEED;
    private double vt;
    private double g = 9.8;
    private double delta_height;
    private double t =0.5;
    /**
     * 跳跃的方法
     */
    public void jump(List<Ground> grounds){
        if (!drop){
            //向上跳
            vt = v0 - g * t;
            delta_height = v0 * t;
            v0 = vt;
            y -= delta_height;
            if (vt <= 0){
                vt = 0;
                drop = true;
            }
        }else {
            jumpDown(msc.grounds);
        }
    }
    private boolean drop = true;
    public void jumpDown(List<Ground> grounds){
        vt = v0 +g *t;
        delta_height = v0 *t;
        v0 = vt;
        y += delta_height;

        for (int i = 0; i < grounds.size(); i++) {
            Ground ground = grounds.get(i);
            if (this.getRectangle().intersects(ground.getRectangle())&& this.y <=ground.y - this.height +40){
                if (this.y >= ground.y - this.height){
                    this.y = ground.y - this.height;
                    drop = false;
                    jump = false;
                    v0 = Constant.INIT_JUMP_SPEED;
                    vt = 0.0;
                    break;
                }
            }else {
                drop = true;
            }
        }
    }

  /*  private void jump() {
        //vt = v0 + gt
        vt = v0 - g * t;
        delta_height = v0 * t;
        v0 = vt;
        y -= delta_height;
        if (y >= 500){
            jump = false;
            v0 = Constant.INIT_JUMP_SPEED;
            vt = 0.0;
            y = 500;
        }

    }*/

    /**
     * 根据当前人物的左右开关,确定人物的方向
     */
    private void confirmDirection(){
        if (left && !right){
            this.dir = Direction.LEFT;
            if (jump){
                this.action = Action.JUMP;
            }
        }else if (right && !left){
            this.dir = Direction.RIGHT;
            if (jump){
                this.action = Action.JUMP;
            }
        }else if (down){
            this.action = Action.PRONE;
        }else if (jump){
            this.action = Action.JUMP;
        }else if (shoot){
            this.action = Action.SHOOT;

        }
        //都按下或者都不按
        else{
            this.action = Action.STAND;
        }
    }

    /**
     * 按键的方法
     * @param e 键盘事件对象
     */
    public void keyPressed(KeyEvent e){
        switch (e.getKeyCode()){
            case KeyEvent.VK_A:
                this.x -=this.speed;
                left = true;
                break;
            case KeyEvent.VK_D:
                this.x +=this.speed;
                right = true;
                break;
            case KeyEvent.VK_S:
                down = true;
                break;
            case KeyEvent.VK_K:
                jump = true;
                break;
            case KeyEvent.VK_J://攻击
                shoot = true;
                break;
            case KeyEvent.VK_L://拾取道具
                pickup = true;
                break;
            case KeyEvent.VK_I://道具包

                break;
            case KeyEvent.VK_W:
                if (this.getRectangle().intersects(msc.ladders.get(0).getRectangle())
                        &&this.y>=msc.ladders.get(0).y-this.height){
                    rope = true;
                    action = Action.ROPE;
                }else  if (this.getRectangle().intersects(msc.ladders.get(1).getRectangle())
                        &&this.y>=msc.ladders.get(1).y-this.height){
                    rope = true;
                    action = Action.ROPE;
                }else if (this.getRectangle().intersects(msc.ladders.get(2).getRectangle())
                        &&this.y>=msc.ladders.get(2).y-this.height){
                    rope = true;
                    action = Action.ROPE;
                }
                else {
                    rope = false;
                }
//                this.y -=10;
//                rope = true;
                break;
            default:
                break;
        }
    }
    /**
     * 按键释放的方法
     * @param e 键盘事件对象
     */
    public void keyReleased(KeyEvent e){
        switch (e.getKeyCode()){
            case KeyEvent.VK_A:
                this.x -=this.speed;
                left = false;
                break;
            case KeyEvent.VK_D:
                this.x +=this.speed;
                right = false;
                break;
            case KeyEvent.VK_S:
                down = false;
                break;
            case KeyEvent.VK_L://拾取
                pickup = false;
                break;
            case KeyEvent.VK_W:
                rope = false;
                break;
            default:
                break;
        }
    }

    /**
     * 人物出界判断
     */
    private void outOfBound(){
        if (this.x <=0){
            this.x =0;
        }
        if (this.x >= Constant.GAME_WIDTH - this.width){
            this.x = Constant.GAME_WIDTH - this.width;
        }
        if (this.dir ==Direction.RIGHT){
        }
        if (this.dir == Direction.LEFT){
            if (this.x <= 530  && this.y >= 730 - this.height + 40){
                this.x = 530;
            }
        }
    }
    /**
     * 拾取道具的方法
     * @return item道具对象
     */
    public boolean pickup(Item item){
        if (item.live && this.getRectangle().intersects(item.getRectangle())){
            item.live = false;
            //存放之间和道具包里的每一个进行判断
            //若相同qty+1
            for(int i=0;i<msc.itemPackage.items.size();i++){
                Item itm = msc.itemPackage.items.get(i);
                if (item.type ==itm.type){
                    itm.qty +=1;
                    return false;
                }
            }
            //业务逻辑 放入道具包
            msc.itemPackage.items.add(item);


    /*       switch (item.type){
               case 0:
                   this.HP +=50;
                   break;
               case 1:
                   this.HP +=100;
                   break;
               case 2:
                   this.HP +=300;
                   break;
               case 3:
                   this.MP +=100;
                   break;
           }
            if (HP >MAX_HP){
                HP = MAX_HP;
            }
            if (MP >MAX_MP){
                MP = MAX_MP;
            }*/

        }
        return false;
    }

    /**
     * 拾取所有道具
     * @param items  道具容器
     * @return 是否拾取到
     */
    public boolean pickup(List<Item> items){
        for (int i = 0; i < items.size(); i++) {
            Item item = items.get(i);
            if (pickup(item)){
                return true;
            }
        }
        return false;
    }
    public Hero.BloodBar bloodBar = new Hero.BloodBar();
    class BloodBar extends AbstractMapleObject{
        private Image  img;
        public BloodBar(){
            this.img = ImageUtil.getImage("blood");
            this.width = img.getWidth(null);
        }
        @Override
        public void draw(Graphics g) {
            int n = Hero.this.width/this.width  * Hero.this.HP/Hero.this.MAX_HP;
            for (int i= 0; i<n;i++ ) {
                g.drawImage(img, Hero.this.x + (i * this.width), Hero.this.y - 22, null);
            }

        }

    }
    public Hero.MP mp = new Hero.MP();
    class MP extends AbstractMapleObject{
        private Image  img;
        public MP(){
            this.img = ImageUtil.getImage("mp");
            this.width = img.getWidth(null);
        }
        @Override
        public void draw(Graphics g) {
            int n = Hero.this.width/this.width  * Hero.this.MP/Hero.this.MAX_MP;
            for (int i= 0; i<n;i++ ) {
                g.drawImage(img, Hero.this.x + (i * this.width), Hero.this.y - 14, null);
            }

        }

    }
}